(function(X, $){
/**
 * @class Xwb.mod.Validators
 * 常用表单验证器集合
 */

var getText = X.lang.getText,

	Util = X.util,
	Req = X.request;

Xwb.ax.ValidationMgr.prototype




//输入框css样式控制
//用法:rel="_ft=text:默认文字,css:css类"
.reg('ft', function(elem, v, data, next){
	if(arguments.length == 2 ){
		var arr = [],data = v;
		for(var i in data){
			switch(i){
				case 'text':arr.push( data[i]!=undefined?data[i]:'' );break;
				case 'css':arr.push( data[i] );break;
				case 'cssNode':arr.push( data.cssNode ? $(elem).closest(data.cssNode) : data.cssNode );break;
				case 'operate':arr.push( +data[i] );break;
				case 'handle' : arr.push( data[i] == 'false' ? false : Boolean(data[i]) );break;
			}
		}

		$(elem).focusText.apply($(elem),arr).data('vrel_ft_text',data.text);
		if(elem.type == 'password' ){
			var next = $(elem).next('input[type="text"]');
			if(next.length == 0) return;
			next.focus(function(){
				 $(elem).cssDisplay(1);
				 next.cssDisplay(0);
				 $(elem).focus();
			});
			$(elem).blur(function(){
				if(this.value == data.text ){
					next.cssDisplay(1);
					$(this).cssDisplay(0);
				}
			})
			.focus(function(e){
				if($(elem).hasClass('hidden')){
					$(elem).cssDisplay(1);
					next.cssDisplay(0);
				}
			});
		}
	} else {
		 // 验证时
        var text = $(elem).data('vrel_ft_text');
        // args:elem, v, data, next
        // 当条件满足时，重置为空值
        if(v == text)
            this.setValue('');
            
        this.report(true, data);
        next();
	}
})

/**
 * @event ne
 * 空检测，标记作为元素必须字段。
 * <pre>
   vrel="ne=w:在这里输入名称,m:请输入昵称"
 * </pre>
 * @param {String} [m] 出错提示文字
 */
.reg('ne', function(elem, v, data, next){
    
    var em = v === '';
    var text = $(elem).data('vrel_ft_text') || data.w;
    if( !em && text ){
        em = v == text;
        // 重置为空，防停留字干扰后来的验证器
        if(em)
            this.setValue('');
    }

    if(em && !data.m)
        data.m = getText('该项不能为空');

    if (elem.tagName === 'INPUT' && ( elem.type === 'radio' || elem.type === 'checkbox' )) 
        em = !elem.checked;
    this.report(!em, data);

    next();
})

/**
 * @event f
 * 失去焦点时验证元素
 * <pre>
    // 失去焦点时验证元素是否为空
    vrel="_f|ne"
 * </pre>
 */
.reg('f', function(elem, data){
    var chain = this;
    var tn = elem.tagName.toLowerCase();
    if(chain.context.comForm && (tn == 'input' || tn == 'textarea')){//设置焦点样式
    	var fc = chain.context.focusCss;
	    $(elem).blur(function(){
	    	$(this).removeClass(fc);
	    	if(!data.ch)//失去焦点检测
	        	chain.validate();
	    }).focus(function(){
	    	$(this).removeClass(chain.context.errCss);
	    	$(this).addClass(fc);
	    });
    }else{
	    $(elem).blur(function(){
	        chain.validate();
	    });
    }
})

/**
 * @event sz
 * 检测输入字符长度
 * 属性：
    <div class="mdetail-params">
    <ul>
    <li>max=number，允许最大字节长度</li>
    <li>min=number，允许最小字节长度</li>
    <li>ww, wide code缩写，将长度按宽字符计算，一个汉字两个字节长度</li>
    <li></li>
    </ul>
    </div>
    例：
    <pre>
        sz=max:6,min:4,m:最少两个汉字，最多三个汉字,ww
    </pre>
 * @param {Number} max 最大长度
 * @param {Number} min 最小长度
 * @param {Boolean} ww 取值1或0，指明长度单位是否按宽字符长度计算，宽字符单位为2，一个字两个字母
 */
.reg('sz', function(elem, v, data, next){
    // 允许空
   if(v){
       var len = data.ww ? Xwb.util.byteLen(v) : v.length,
           err, 
           max = data.max, 
           min = data.min;
       if(max !== undefined && parseInt(max) < len)
            err = true;
       if(min !== undefined && parseInt(min)>len)
            err = true;
       this.report(!err, data);
   }else this.report(true, data);
   
   next();
})
/**
 * @event dt
 * 检查是否有效的日期格式
 * <pre><code>
 * vrel="dt"
 * </code></pre>
 */

.reg('dt', function(elem, v, data, next){
    if(v){
        if(!data.m)
            data.m = getText('不是有效的日期格式');
        var d = Date.parse(v);
        // 可以在这扩展max,min等
        this.report(!isNaN(d), data);
    }else this.report(true, data);
    next();
})
/**
 * @event mail
 * 验证是否为邮箱格式
 * <pre><code>
 * vrel="mail"
 * </code></pre>
 */

.reg('mail', function(elem, v, data, next){
    if(v){
    	var result = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(v);
        if(!data.m && data.m !== 0)
            data.m = getText('请输入正确的邮箱格式');
    	this.report(result, data);
    }else this.report(true, data);
	next();
})
.reg('mobile', function(elem, v, data, next){
	if(v){
		var result = /(^[0-9]{3,4}\-[0-9]{7,8}$)|(^[0-9]{7,8}$)|(^\([0-9]{3,4}\)[0-9]{3,8}$)|(^0{0,1}1[0-9][0-9]{9}$)/.test(v);
        if(!data.m && data.m !== 0)
            data.m = getText('请输入正确的手机号码');
    	this.report(result, data);
    }else this.report(true, data);
	next();
})

/**
 * @event int
 * 验证是否为数字格式
 * <pre><code>
 * vrel="int|sz=max:5,min:1"
 * </code></pre>
 */

.reg('int', function(elem, v, data, next) {
    if(v !== ''){
    	var result = v && /^\d+$/.test(v);
        if(!data.m && data.m !== 0)
            data.m = getText('该项为数字格式');
    	this.report(result, data);
    }else this.report(true, data);
	next();
})

/**
 * @event bt
 * 验证是值是否在某个整数范围内
 * <pre><code>
 * vrel="bt=max:1000,min:1"
 * </code></pre>
 * @param {Number} max 
 * @param {Number} min
 */

.reg('bt', function(elem, v, data, next) {
    if(v !== ''){
    	var min = parseInt(data.min),
    		max = parseInt(data.max),
    		v = parseInt(v),
    		err = 0;
    
    	if (v < min)
    		err = 1;
    
    	if (!err && (v > max))
    		err = 2
    
    	this.report(!err, data);
    }else this.report(true, data);
	next();
})
/**
 * @event sinan
 * 检查昵称是否为非法字符。非法字符指除中英文、数字、"_"或减号符号外的所有字符
 * <pre><code>
 * vrel="sinan"
 * </code></pre>
 */

.reg('sinan', function(elem, v, data, next){
    if(v){
        if(!data.m)
            data.m = getText('支持中英文、数字、"_"或减号');
        this.report(/^[a-zA-Z0-9\u4e00-\u9fa5_-]+$/.test(v), data);
    }else this.report(true, data);
    next();
})

//url地址　
.reg('url',function(elem, v, data, next){
	var reg = /^(http[s]?):\/\/[^\/\.]+?\..+\w$/i;
	//var reg = /^http(s)?:\/\/(?!([\w-]+\.[\w-]+$))([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?$/;
	if(v){
	if(!data.m)
	data.m = getText('不合格的url格式');
	this.report(reg.test(v), data);
	} else this.report(true, data);
	next();
})

//在输入框上加一个label的提示标签
.reg('lab',function(elem, v, data, next){
	var labId = (data && data.lid) || (elem.id+'Lab'), _this = $(elem), lab = $('#'+labId), css = v.css == ''?'':(v.css?v.css:'actived');
	lab.click(function(e){
		_this.focus();		
	});
	_this.blur(function(e){
		if(Util.trim(this.value) == ''){
			lab.cssDisplay(1);
		}
		if(css){
			_this.removeClass(css);
		}
	}).keyup(function(e){
		if(this.value) lab.cssDisplay(0);
		else lab.cssDisplay(1);
	}).focus(function(e){
		if(css){
			_this.addClass(css);			
		}
	})	
	if(lab.length)
		_this.val('');
})

.reg('')

//两元素比较
.reg('ct',function(elem, v, data, next){
	var ct = $(data.node),init=$(elem).data('init'),mgm = this;
	if(!init){
		$(elem).data('init',true);
		ct.blur(function(){
			mgm.validate();
		});
	}
	var flag = true, ctv = $.trim(ct.val() );
	switch(data.operate){
		case 'not' : 
			flag = !ctv||!v||( v !== ctv );
			break;
		default :
			flag = !ctv||!v||( v === ctv );
			break;
	}
	this.report(  flag, data);
	next(); 
})
//两次密码匹配
.reg("cpw",function(elem, v, data, next){
    if(v != $("#password").val()){
		this.report(false, data);
	}
	next();
})
//两次密码匹配
.reg("cpw1",function(elem, v, data, next){
    if(v != $("#password1").val()){
		this.report(false, data);
	}
	next();
})
//qq验证
.reg('qq', function(elem,v,data,next){
    var flag = true;
    if(v != ''){
	   flag = /^[1-9]\d{4,9}$/.test(v);
	   data.m = "<em>qq号码为5－10为数字</em>"
	}
	this.report( flag, data);
	next();
})

//异步检测邮箱
.reg("mailCk",function(elem,v,data,next){
	var tthis = this;
	if(v == ''){
		//data.m = '<em>该项不能为空</em>';
		tthis.report(true, data); next();   //邮箱可为空
	}
	else if( v.length > 50 ){
		data.m = '<em>不能超过50个字符</em>';
		tthis.report(false, data); next();
	}
	else if(!/^([a-zA-Z0-9]+[\-_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/.test(v)){
		data.m = '<em>请输入正确的邮箱格式</em>';
		tthis.report(false, data); next();
	}
	else {
	    if(data.t === "modify"){
		   	var $inp = $(elem);
			if( $inp.val() == $inp.attr("initvalue")){
			    tthis.report(true, data);
		    	next();
		    	return false;
	    	}
		}
		Req.postReq(Req.mkUrl('jsApi/accountApi','checkEmail'),{email: v}, function(e){
			if(e.isOk())
				tthis.report(true, data);
			else  {
				data.m = '<em>'+  e.getError() + '</em>';
				tthis.report(false, data);
			}
			next();
		});
	}
})
//异步检测呢称
.reg("nickCk",function(elem,v,data,next){
	var tthis = this,
	    len = Util.byteLen(v); //计算字符长度
	if(v == ''){
		data.m = '<em>该项不能为空</em>';
		tthis.report(false, data); next();
	}
	else if(!/^[a-zA-Z0-9\u4e00-\u9fa5_-]+|\(\)$/.test(v)){
		data.m = '<em>该昵称包含了非法字符</em>';
		tthis.report(false, data); next();
	}
	else if( len < 4 || len > 20 ){
		data.m = '<em>4-20个字符</em>';
		tthis.report(false, data); next();
	}
	else {
	    if(data.t === "modify"){
		   	var $inp = $(elem);
			if( $inp.val() == $inp.attr("initvalue")){
			    tthis.report(true, data);
		    	next();
		    	return false;
	    	}
		}
		Req.postReq(Req.mkUrl('jsApi/accountApi','checkNick'),{nickname: v},  function(e){
			if(e.isOk())
				tthis.report(true, data);
			else  {
				data.m = '<em>'+  Req.ERRORMAP[ e.getCode() ] ||  e.getError() + '</em>';
				tthis.report(false, data);
			}
			next();
		});
	}
})
//异步检测验证码
.reg("vcode",function(elem,v,data,next){
    var tthis = this;
	if(v == ''){
		data.m = '<em>验证码不能为空</em>';
		tthis.report(false, data); next();
	}
	else {
		Req.postReq(Req.mkUrl('jsApi/accountApi','validRegCode'),{verify_code: v},  function(e){
			if(e.isOk())
				tthis.report(true, data);
			else  {
				data.m = '<em>'+ e.getError() + '</em>';
				tthis.report(false, data);
			}
			next();
		});
	}
})

})(Xwb, $);
